package com.fangzhi.controller;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fangzhi.mobel.*;
import com.fangzhi.mobel.dto.OrderExcelDto;
import com.fangzhi.mobel.vo.DeptListVo;
import com.fangzhi.mobel.vo.LoginVo;
import com.fangzhi.mobel.vo.RoleListVo;
import com.fangzhi.service.*;
import com.fangzhi.utils.GlobalParam;
import com.fangzhi.utils.SendDingDingUtil;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.awt.Color;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/download")
public class DownloadController {


    @Autowired
    private OrderReceiptService orderReceiptService;
    @Autowired
    private OrdersService ordersService;
    @Autowired
    private OrderProductsService orderProductsService;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private ProductTypeService productTypeService;
    @Autowired
    private ProductTechnologyService productTechnologyService;
    @Autowired
    private RoleBaseInfoService roleBaseInfoService;
    @Autowired
    private DeptBaseInfoService deptBaseInfoService;
    @Autowired
    private AdminAccountInfoService adminAccountInfoService;
    @Autowired
    private BadTypeService badTypeService;
    @Value("${com.aliyun.endpoint}")
    private String endpoint;
    @Value("${com.aliyun.accessKeyId}")
    private String accessKeyId;
    @Value("${com.aliyun.accessKeySecret}")
    private String accessKeySecret;

    /**
     * 下载orders 订单
     *
     * @param response
     * @param request
     * @return
     * @throws IOException
     */
    @GetMapping("/downloadOrderExcel")
    public synchronized ResponseEntity<byte[]> downloadOrderExcel(@RequestParam(defaultValue = "") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startTime
            , @RequestParam(defaultValue = "") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endTime
            , @RequestParam String deptId
            , @RequestParam(defaultValue = "0") Integer userId
            , @RequestParam(defaultValue = "") String name
            , @RequestParam(defaultValue = "") String orderId
            , HttpServletResponse response, HttpServletRequest request) throws IOException {
        List<RoleListVo> roleListVos = roleBaseInfoService.roleList(0);
        List<DeptListVo> deptListVos = new ArrayList<>();
        if (StringUtils.isEmpty(deptId)) {
            deptListVos = deptBaseInfoService.deptList(0);
        } else {
            deptListVos = deptBaseInfoService.deptList1(deptId);
        }
        if (roleListVos.isEmpty() || deptListVos.isEmpty())
            return null;

        int accountId = 0;
        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        if (loginVo.getRoleId() == 3)
            accountId = loginVo.getId().intValue();

        List<Long> roleIds = roleListVos.stream().map(T -> T.getId()).collect(Collectors.toList());
        List<Long> deptIds = deptListVos.stream().map(T -> T.getId()).collect(Collectors.toList());
        List<Long> accountIds = adminAccountInfoService.accountList(roleIds, deptIds, accountId);
        if (accountIds.isEmpty())
            return null;
        List<OrderExcelDto> list = ordersService.queryOrderExcelList(orderId, name, startTime, endTime, accountIds, userId);
        String excelName = UUID.randomUUID().toString();
        createExcel(list, excelName);
        String property = System.getProperty("user.dir");
        // 将文件上传oss
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        File file = new File(property + "/excel/"+ excelName + ".xlsx");
        ossClient.putObject("weiyunfangzhi-image", "excel/" + excelName + ".xlsx", new FileInputStream(file));
        // 上传成功通知钉钉
        SendDingDingUtil.SendMessage( startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) +"至"
                + endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), excelName + ".xlsx");
        byte[] fileContent = Files.readAllBytes(new File(property + "/excel/" + excelName + ".xlsx").toPath()); // 注意：这种方式适合小文件
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=历史报价表.xlxs");
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
        return ResponseEntity.ok()
                .headers(headers)
                .body(fileContent);
    }

    public void createExcel(List<OrderExcelDto> list, String excelName) throws IOException {
        LoginVo loginVo = GlobalParam.LOGIN_ACCOUNT_INFO.get();
        String property = System.getProperty("user.dir");
        // 加载Excel模板
        String excelPath = "/excel/order-excel.xlsx";
        if (loginVo.getRoleId() == 5)
            excelPath = "/excel/order-excel-caiwu.xlsx";
        FileInputStream fileInputStream = new FileInputStream(property + excelPath);
        XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
        XSSFSheet sheet = workbook.getSheetAt(0);
        sheet.createFreezePane(0, 1);
        for (int i = 0; i < list.size(); i++) {
            OrderExcelDto orders = list.get(i);
            XSSFRow row = sheet.createRow(1 + i);
            Cell cell = row.createCell(0);
            cell.setCellValue(orders.getTime());
            // 订单号
            cell = row.createCell(1);
            cell.setCellValue(orders.getOrderId());
            // 销售部门
            cell = row.createCell(2);
            cell.setCellValue(orders.getDeptName());
            // 业务员
            cell = row.createCell(3);
            cell.setCellValue(orders.getUserName());
            // 收货地址
            cell = row.createCell(4);
            cell.setCellValue(orders.getAddress());
            // 收件人
            cell = row.createCell(5);
            cell.setCellValue(orders.getCustomerName());
            // 电话
            cell = row.createCell(6);
            cell.setCellValue(orders.getCustomerTotal());
            // 酒店名字
            cell = row.createCell(7);
            cell.setCellValue(orders.getHotelName());
            // 总金额
            cell = row.createCell(8);
            cell.setCellValue(orders.getTotalAmount());
            // 回款金额
            cell = row.createCell(9);
            cell.setCellValue(orders.getDepositAmount());
            // 物流代收
            cell = row.createCell(10);
            cell.setCellValue(orders.getLgtsCollect());
            // 是否包邮
            cell = row.createCell(11);
            if (orders.getFreeShippingType() == 1) {
                cell.setCellValue("包邮");
            } else if (orders.getFreeShippingType() == 2) {
                cell.setCellValue("不包邮");
            }

            // 新老报价
            cell = row.createCell(12);
            cell.setCellValue("新报价");
            if (orders.getPriceType() == 2)
                cell.setCellValue("特价报价");
            // 员工底价
            List<OrderProducts> orderProductsList = orderProductsService.list(Wrappers.<OrderProducts>lambdaQuery()
                    .eq(OrderProducts::getOrderId, orders.getOrderId()));
            double price = getPrice(orderProductsList);
            cell = row.createCell(13);
            cell.setCellValue(price);
            // 新老用户
            cell = row.createCell(14);
            switch (orders.getCustomerType()) {
                case 1:
                    cell.setCellValue("老用户");
                    break;
                case 2:
                    cell.setCellValue("新用户");
                    break;
                case 3:
                    cell.setCellValue("样品客户");
                    break;
                case 4:
                    cell.setCellValue("样品客户（已发过样品）");
            }
            // 如果是财务则绘制  回执图
            if (loginVo.getRoleId() == 5) {
                XSSFCellStyle style = workbook.createCellStyle();
                byte[] rgb = new byte[3];
                rgb[0] = (byte) 134; // 红
                rgb[1] = (byte) 204; // 绿
                rgb[2] = (byte) 88; // 蓝
                XSSFColor customColor = new XSSFColor(rgb, null);
                style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                style.setFillForegroundColor(customColor);
                style.setAlignment(HorizontalAlignment.CENTER);
                style.setVerticalAlignment(VerticalAlignment.CENTER);
                List<OrderReceipt> orderReceipts = orderReceiptService.list(Wrappers.<OrderReceipt>lambdaQuery()
                        .eq(OrderReceipt::getOrderId, orders.getOrderId()));
                if (orderReceipts.isEmpty())
                    continue;
                row = sheet.getRow(0);
                cell = row.createCell(15);
                cell.setCellValue("运费合计");
                cell.setCellStyle(style);
                cell = row.createCell(16);
                cell.setCellValue("金额合计");
                cell.setCellStyle(style);
                Integer cellNumber = 16;
                for (OrderReceipt orderReceipt : orderReceipts) {
                    for (int i2 = 0; i2 < 4; i2++) {
                        cellNumber += 1;
                        cell = row.createCell(cellNumber);
                        if (i2 == 0) {
                            cell.setCellValue("厂家");
                            cell.setCellStyle(style);
                        } else if (i2 == 1) {
                            cell.setCellValue("运费");
                            cell.setCellStyle(style);
                        } else if (i2 == 2) {
                            cell.setCellValue("金额");
                            cell.setCellStyle(style);
                        } else {
                            cell.setCellValue("回执图");
                            cell.setCellStyle(style);
                        }
                    }
                }

                style = workbook.createCellStyle();
                style.setAlignment(HorizontalAlignment.CENTER);
                style.setVerticalAlignment(VerticalAlignment.CENTER);
                Integer totalFee = 0;
                Integer totalAmount = 0;
                row = sheet.getRow(1 + i);
                cellNumber = 16;
                for (OrderReceipt orderReceipt : orderReceipts) {
                    for (int i2 = 0; i2 < 4; i2++) {
                        cellNumber += 1;
                        cell = row.createCell(cellNumber);
                        cell.setCellStyle(style);
                        if (i2 == 0) {
                            cell.setCellValue(orderReceipt.getReceiptCompany());
                        } else if (i2 == 1) {
                            totalFee += orderReceipt.getReceiptShippingFee();
                            cell.setCellValue(orderReceipt.getReceiptShippingFee() / 100D);
                        } else if (i2 == 2) {
                            totalAmount += orderReceipt.getReceiptTotalAmount();
                            cell.setCellValue(orderReceipt.getReceiptTotalAmount() / 100D);
                        } else {
                            if (!StringUtils.hasText(orderReceipt.getImage()))
                                continue;
                            URL imageUrl = new URL(GlobalParam.IMAGE_URL + orderReceipt.getImage());
                            InputStream imageStream = imageUrl.openStream();
                            byte[] bytes = IOUtils.toByteArray(imageStream);
                            XSSFDrawing drawing = sheet.createDrawingPatriarch();
                            XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, cell.getColumnIndex(), row.getRowNum(), cell.getColumnIndex() + 1, row.getRowNum() + 1);
                            int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
                            XSSFPicture picture = drawing.createPicture(anchor, pictureIdx);
                            picture.resize(1, 1);
                            imageStream.close();
                        }
                    }
                }
                cell = row.createCell(15);
                cell.setCellValue(totalFee / 100D);
                cell = row.createCell(16);
                cell.setCellValue(totalAmount / 100D);
            }
        }
        FileOutputStream fileOutputStream = new FileOutputStream(property + "/excel/" + excelName + ".xlsx");
        workbook.write(fileOutputStream);
        workbook.close();
        fileOutputStream.close();
    }

    public double getPrice(List<OrderProducts> orderProductsList) {
//        List<Long> technologyIds = new ArrayList<>();
//        orderProductsList.parallelStream().forEach(T-> technologyIds.addAll(JSON.parseArray(T.getTechnologyId(), Long.class)));
//        List<ProductTechnology> productTechnologies = productTechnologyService.list(Wrappers.<ProductTechnology>lambdaQuery()
//                .in(ProductTechnology::getId, technologyIds));
//        Map<Long, ProductTechnology> map = new HashMap<>();
//        productTechnologies.forEach(T -> map.put(T.getId(), T));
        double sum = orderProductsList.stream().mapToDouble(T -> {
            List<Long> technologyIds = JSON.parseArray(T.getTechnologyId(), Long.class);
            int technologyPrice = 0;
            if (!technologyIds.isEmpty()){
                List<ProductTechnology> list = productTechnologyService.list(Wrappers.<ProductTechnology>lambdaQuery()
                        .in(!technologyIds.isEmpty(), ProductTechnology::getId, technologyIds));
                technologyPrice = list.stream().mapToInt(ProductTechnology::getPrice).sum();
            }
            return (T.getPrice() + technologyPrice) * T.getNum() / 100D;
        }).sum();
        return sum;
    }

    /**
     * 下载彪哥
     *
     * @param orderId
     * @param type
     * @return
     */
    @GetMapping("/downloadExcelByType")
    public synchronized ResponseEntity<byte[]> downloadExcelByType(@RequestParam String orderId
            , @RequestParam(defaultValue = "2") Integer type
            , HttpServletResponse response, HttpServletRequest request) throws IOException {

        String property = System.getProperty("user.dir");
        createExcel2(orderId, property);
        String resoure = property + "/excel/new.xlsx";
        byte[] fileContent = Files.readAllBytes(new File(resoure).toPath()); // 注意：这种方式适合小文件

        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + orderId + "\"");
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
        return ResponseEntity.ok()
                .headers(headers)
                .body(fileContent);
    }

    public void createExcel2(String orderId, String property) throws IOException {
        Orders one = ordersService.getOne(Wrappers.<Orders>lambdaQuery().eq(Orders::getOrderId, orderId));
        Customer byId = customerService.getById(one.getCustomer());
        List<OrderProducts> list = orderProductsService.queryListByType(1, orderId);
        int productNum;
        if (list.size() <= 4) {
            productNum = 5;
        } else if (list.size() <= 9) {
            productNum = 10;
        } else if (list.size() <= 14) {
            productNum = 15;
        } else if (list.size() <= 24) {
            productNum = 25;
        } else if (list.size() <= 34) {
            productNum = 35;
        } else if (list.size() <= 44) {
            productNum = 45;
        } else if (list.size() <= 54) {
            productNum = 55;
        } else {
            productNum = 70;
        }

        // 加载Excel模板
        FileInputStream fileInputStream = new FileInputStream(property + "/excel/excel2-" + productNum + ".xlsx");
        XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
        XSSFSheet sheet = workbook.getSheetAt(0);
        Row row = sheet.getRow(1);
        // 订单号
        Cell cell = row.getCell(1);
        cell.setCellValue(one.getOrderId());
        // 下单时间
        cell = row.getCell(4);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        cell.setCellValue(one.getCtime().format(dateTimeFormatter));
        // 客户名称
        row = sheet.getRow(2);
        cell = row.getCell(1);
        cell.setCellValue(byId.getName());
        // 出货日期
        cell = row.getCell(4);
        cell.setCellValue("");

        int rowNum = 4;
        for (OrderProducts orderProducts : list) {
            Integer price = orderProducts.getPrice() + orderProducts.getPremiumPrice();
            row = sheet.getRow(rowNum);
            // 品名
            cell = row.getCell(0);
            String badTypeName = "";
            if (orderProducts.getBadTypeId() > 0) {
                BadType badType = badTypeService.getById(orderProducts.getBadTypeId());
                if (null != badType)
                    badTypeName = "+" + badType.getName();
            }
            cell.setCellValue(orderProducts.getOne() + badTypeName);
            // 规格尺寸
            cell = row.getCell(1);
            cell.setCellValue(orderProducts.getTwo());
            // 材质要求
            cell = row.getCell(2);
            cell.setCellValue(orderProducts.getThree());
            // 备注
            List<Long> longs = JSON.parseArray(orderProducts.getTechnologyId(), long.class);
            List<ProductTechnology> technologyList = new ArrayList<>();
            StringBuilder sb = new StringBuilder();
            if (!longs.isEmpty())
                technologyList = productTechnologyService.list(Wrappers.<ProductTechnology>lambdaQuery()
                        .in(!longs.isEmpty(), ProductTechnology::getId, longs));
            technologyList.forEach(T -> sb.append(T.getName()).append("+"));
            cell = row.getCell(3);
            cell.setCellValue(sb + orderProducts.getComments());
            // 数量
            cell = row.getCell(4);
            cell.setCellValue(orderProducts.getNum());
            // 单价
            cell = row.getCell(5);
            cell.setCellValue(price / 100D);
            // 金额
            cell = row.getCell(6);
            cell.setCellValue(orderProducts.getTotalAmount() / 100D);
            rowNum += 1;
        }
        // 备注
        row = sheet.getRow(productNum + 4);
        cell = row.getCell(1);
        cell.setCellValue(one.getComments());
        // 总额
        cell = row.getCell(5);
        cell.setCellValue("总额");
        cell = row.getCell(6);
        cell.setCellValue(one.getTotalAmount() / 100D);
        // 优惠
        row = sheet.getRow(productNum + 5);
        cell = row.getCell(1);
        switch (one.getFreeShippingType()) {
            case 1:
                cell.setCellValue("包邮");
                break;
            case 2:
                cell.setCellValue("不包邮");
                break;
        }
        cell = row.getCell(5);
        cell.setCellValue("优惠");
        cell = row.getCell(6);
        cell.setCellValue(one.getDiscountAmount() / 100D);
        // 定金
        row = sheet.getRow(productNum + 6);
        cell = row.getCell(5);
        cell.setCellValue("定金");
        cell = row.getCell(6);
        cell.setCellValue(one.getDepositAmount() / 100D);
        // 物流代收
        row = sheet.getRow(productNum + 7);
        cell = row.getCell(5);
        cell.setCellValue("物流代收");
        cell = row.getCell(6);
        cell.setCellValue((one.getTotalAmount() - one.getDiscountAmount() - one.getDepositAmount()) / 100D);
        // 收货地址
        row = sheet.getRow(productNum + 8);
        cell = row.getCell(1);
        cell.setCellValue(byId.getProvince() + byId.getCity() + byId.getArea() + byId.getDescs() + "      联系电话：" + byId.getTotal());

        List<String> strings = JSON.parseArray(one.getImageComments(), String.class);
        for (int i = 0; i < strings.size(); i++) {
            row = sheet.getRow(productNum + 3);
            cell = row.getCell(0);
            // 创建绘图对象
            URL imageUrl = new URL(GlobalParam.IMAGE_URL + strings.get(i));
            InputStream imageStream = imageUrl.openStream();
            byte[] bytes = IOUtils.toByteArray(imageStream);
            XSSFDrawing drawing = sheet.createDrawingPatriarch();
            XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, cell.getColumnIndex() + i, row.getRowNum(), cell.getColumnIndex() + 1 + i, row.getRowNum() + 1);
            int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
            XSSFPicture picture = drawing.createPicture(anchor, pictureIdx);
            picture.resize(1, 1);
            imageStream.close();
        }
        FileOutputStream fileOutputStream = new FileOutputStream(property + "/excel/new.xlsx");
        workbook.write(fileOutputStream);
        workbook.close();
        fileOutputStream.close();
    }


}
